﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Net;
using Speakup;
using WebLayer;
using System.Windows.Threading;

namespace SpeakupUI
{
    class WebPanel: ContentControl
    {

        Settings Settings;
        TimeSheet TimeSheet;
        ClassPanelList ClassPanelList;

        Label UserLabel;
        TextBox User;

        Label PasswordLabel;
        PasswordBox Password;

        Label SchoolLabel;
        TextBox School;

        Button RefreshButton;

        WaitDialog WaitDialog = new WaitDialog();

        public WebPanel(Settings settings, TimeSheet timeSheet, ClassPanelList classes)
        {
            Settings = settings;
            TimeSheet = timeSheet;
            ClassPanelList = classes;

            Grid grid = new Grid();
            grid.RowDefinitions.Add(new RowDefinition());
            grid.RowDefinitions.Add(new RowDefinition());
            grid.RowDefinitions.Add(new RowDefinition());
            grid.RowDefinitions.Add(new RowDefinition());
            grid.ColumnDefinitions.Add(new ColumnDefinition());
            grid.ColumnDefinitions.Add(new ColumnDefinition());

            UserLabel = new Label();
            UserLabel.Content = "User";

            User = new TextBox();
            User.Text = Settings.User;
            User.TextChanged += SettingsChanged;

            PasswordLabel = new Label();
            PasswordLabel.Content = "Password";

            Password = new PasswordBox();            
            Password.Password = Settings.Password;            
            Password.PasswordChanged += PasswordChanged; 

            
            SchoolLabel = new Label();
            SchoolLabel.Content = "School";


            School = new TextBox();
            School.Text = Settings.School;
            School.TextChanged += SettingsChanged;

            RefreshButton = new Button();
            RefreshButton.Content = "Refresh";
            RefreshButton.Margin = new Thickness(3);
            RefreshButton.Click += Refresh;

            grid.Children.Add(UserLabel);
            Grid.SetColumn(UserLabel, 0);
            Grid.SetRow(UserLabel, 0);

            grid.Children.Add(User);
            Grid.SetColumn(User, 1);
            Grid.SetRow(User, 0);

            grid.Children.Add(PasswordLabel);
            Grid.SetColumn(PasswordLabel, 0);
            Grid.SetRow(PasswordLabel, 1);

            grid.Children.Add(Password);
            Grid.SetColumn(Password, 1);
            Grid.SetRow(Password, 1);

            grid.Children.Add(SchoolLabel);
            Grid.SetColumn(SchoolLabel, 0);
            Grid.SetRow(SchoolLabel, 2);

            grid.Children.Add(School);
            Grid.SetColumn(School, 1);
            Grid.SetRow(School, 2);            

            grid.Children.Add(RefreshButton);
            Grid.SetColumn(RefreshButton, 0);
            Grid.SetColumnSpan(RefreshButton, 2);
            Grid.SetRow(RefreshButton, 3);
            
            GroupBox box = new GroupBox();
            box.Header = "Web";
            box.Content = grid;
            Content = box;
        }

        WebFetcher WebFetcher = null;
        void Refresh(object sender, RoutedEventArgs e)
        {
            WebFetcher = new WebFetcher(Settings.User, Settings.Password, Settings.School);
            WebFetcher.Completed += RefreshCompleted;
            
            WaitDialog = new WaitDialog();
            WaitDialog.Owner = Application.Current.MainWindow;
            WaitDialog.AllowClose = false;
            WaitDialog.Closing += CancelRefresh;
            WaitDialog.Left = WaitDialog.Owner.ActualWidth / 3 + WaitDialog.Owner.Left;
            WaitDialog.Top = WaitDialog.Owner.ActualHeight / 3 + WaitDialog.Owner.Top;

            WaitDialog.Show();
            Application.Current.MainWindow.IsEnabled = false;
            
            WebFetcher.Fetch();           
        }

        void CancelRefresh(object sender, EventArgs args)
        {
            if (WebFetcher != null)
            {
                WebFetcher.Cancel();
            }
        }

        void RefreshCompleted(object sender, WebFetcherCompleteArgs args)
        {
            if (WaitDialog != null)
            {
                WaitDialog.Closing -= CancelRefresh;
                WaitDialog.AllowClose = true;
                WaitDialog.Close();
                WaitDialog = null;
            }
            WebFetcher = null;

            Application.Current.MainWindow.IsEnabled = true;

            if (args.Classes == null)
            {
                string msg = "Failed to request data from server";
                if (args.Message != null)
                {
                    msg += "\n" + args.Message;
                }

                MessageBox.Show(Application.Current.MainWindow,
                                msg,"Web operatin failed", 
                                MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
            }
            else
            {
                PostRefresh(args.Classes);
                MessageBox.Show(Application.Current.MainWindow,
                                "Successfuly updated data from Speakup web-site.","Done!",
                                MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }

        }

        void PostRefresh(ClassList classes)
        {
            classes.Save();

            foreach (ClassPanel panel in ClassPanelList.Panels)
            {
                TimeSheet.RemoveChildren(panel);
            }

            CreateDiffList(ClassPanelList);

            foreach (ClassPanel panel in ClassPanelList.Panels.ToList<ClassPanel>())
            {
                ClassPanelList.Remove(panel);
            }

            ApplyDiffList(classes);

            foreach (Class speakupClass in classes)
            {
                ClassPanelList.Add(new ClassPanel(speakupClass));
            }

            foreach (ClassPanel panel in ClassPanelList.Panels)
            {
                TimeSheet.AddChildren(panel);
            }

            classes.Save();
        }

        void UpdateSettingsFromUI()
        {
            Settings.Password = Password.Password;
            Settings.User = User.Text;
            Settings.School = School.Text;
            Settings.Save();
        }

        void PasswordChanged(object sender, RoutedEventArgs e)
        {
            UpdateSettingsFromUI();
        }

        void SettingsChanged(object sender, TextChangedEventArgs e)
        {
            UpdateSettingsFromUI();
        }

        ClassList DiffList = null;

        void CreateDiffList(ClassPanelList oldList)
        {
            DiffList = new ClassList();
            foreach (ClassPanel panel in oldList.Panels)
            {
                if (panel.SpeakupClass.Modified)
                {
                    DiffList.Add(panel.SpeakupClass);
                }
            }
        }

        void ApplyDiffList(ClassList newList)
        {
            if (DiffList == null) return;

            foreach (Class modifiedClass in DiffList)
            {
                foreach (Class speakupClass in newList)
                {
                    if (speakupClass.ClassTime.Begin == modifiedClass.ClassTime.Begin &&
                        speakupClass.ClassTime.End == modifiedClass.ClassTime.End &&
                        speakupClass.ClassTime.Date.Date == modifiedClass.ClassTime.Date.Date &&
                        speakupClass.ClassStatus == modifiedClass.PreviousStatus &&
                        speakupClass.ClassId == modifiedClass.ClassId)
                    {
                        speakupClass.DesiredStatus = modifiedClass.ClassStatus;
                    }
                }
            }
        }
    }
}
